

#ifndef	__HELP_MICROTIME_HPP__
#define	__HELP_MICROTIME_HPP__

#include	<time.h>
#include	<sys/time.h>

namespace	test
{

struct	microtime_t	
{
public	:
	microtime_t() :	m_sec(0), m_usec(0) {}
	microtime_t( const struct timeval& rhs ) : m_sec(rhs.tv_sec), m_usec(rhs.tv_usec) {}
	
public	:
	microtime_t&	operator=( int iSeconds )
    {
    	if ( iSeconds >= 0 ) {
    		this->m_sec = iSeconds;
    		this->m_usec = 0;
    	}
    	
    	return	*this;
    }
	 
	microtime_t	operator-( const microtime_t& rhs )
    {
    	microtime_t	result;
    	
    	result.m_usec = this->m_usec - rhs.m_usec;
    	if ( result.m_usec < 0 ) {
    		result.m_sec = this->m_sec - (rhs.m_sec + 1);
    		result.m_usec += 1000000;
    	}
    	else {
    		result.m_sec = this->m_sec - rhs.m_sec;
    	}
    	
    	return	result;
    }
    
	microtime_t	operator+( const microtime_t& rhs )
    {
    	microtime_t	result;
    	
    	result.m_usec = this->m_usec + rhs.m_usec;
    	if ( result.m_usec >= 1000000 ) {
    		result.m_sec = this->m_sec + (rhs.m_sec + 1);
    		result.m_usec -= 1000000;
    	}
    	else {
    		result.m_sec = this->m_sec + rhs.m_sec;
    	}
    	
    	return	result;
    }
	
	microtime_t&	operator-=( const microtime_t& rhs )
    {
    	this->m_usec -= rhs.m_usec;
    	if ( this->m_usec < 0 ) {
    		this->m_sec -= (rhs.m_sec + 1);
    		this->m_usec += 1000000;
    	}
    	else {
    		this->m_sec -= rhs.m_sec;
    	}
    	
    	return	*this;
    }

	microtime_t&	operator+=( const microtime_t& rhs )
    {
    	this->m_usec += rhs.m_usec;
    	if ( this->m_usec >= 1000000 ) {
    		this->m_sec += (rhs.m_sec + 1);
    		this->m_usec -= 1000000;
    	}
    	else {
    		this->m_sec += rhs.m_sec;
    	}
    	
    	return	*this;
    }
	
	microtime_t	operator-( int iSeconds )
    {
    	microtime_t	result;
    	
    	result.m_usec = this->m_usec;
    	result.m_sec = this->m_sec - iSeconds;
    	
    	return	result;
    }

	microtime_t	operator+( int iSeconds )
    {
    	microtime_t	result;
    	
    	result.m_usec = this->m_usec;
    	result.m_sec = this->m_sec + iSeconds;
    	
    	return	result;
    }
	
	microtime_t&	operator-=( int iSeconds )
    {
    	this->m_sec -= iSeconds;
    	
    	return	*this;
    }
    
	microtime_t&	operator+=( int iSeconds )
    {
    	this->m_sec += iSeconds;
    	
    	return	*this;
    }
	
	bool	operator<( const microtime_t& rhs )
    {
        if (this->m_sec < rhs.m_sec) {
            return    true;
        }
        else if ((this->m_sec == rhs.m_sec) && (this->m_usec < rhs.m_usec)) {
            return    true; 
        }
        
        return    false;
    }

	bool	operator==( const microtime_t& rhs )
    {
        if ((this->m_sec == rhs.m_sec) && (this->m_usec == rhs.m_usec)) {
            return    true; 
        }
        
        return    false;
    }

	bool	operator>( const microtime_t& rhs )
    {
        if (this->m_sec > rhs.m_sec) {
            return    true;
        }
        else if ((this->m_sec == rhs.m_sec) && (this->m_usec > rhs.m_usec)) {
            return    true; 
        }
        
        return    false;
    }

	operator double ()
    {
    	double	d = this->m_sec + (this->m_usec / 1000000.0);
    	
    	return	d;
    }
	
	const char*	c_str()
    {
#ifdef	__FreeBSD__
    	int	iSize = snprintf( m_szBuf, sizeof(m_szBuf) - 1, "%u.%06lu", this->m_sec, this->m_usec );
#else
    	int	iSize = snprintf( m_szBuf, sizeof(m_szBuf) - 1, "%lu.%06lu", this->m_sec, this->m_usec );
#endif
    
    	m_szBuf[ iSize ] = '\0';	
    	
    	return	m_szBuf;
    }

public	:
	time_t      m_sec;     /* seconds */
	suseconds_t m_usec;    /* microseconds */
	
private	:
	char	m_szBuf[ 32 ];
};
typedef	struct microtime_t	microtime_t;


microtime_t		microtime( void )
{
	struct	timeval	tm;
	
	gettimeofday( &tm, NULL );
	
	return	tm;
}

}	// namespace help

#endif	// __HELP_MICROTIME_HPP__



